function XmlDataParser(dom) {
	// ---
	this.dom = dom;
	this.ELEMENT_NODE = 1; //dom.ELEMENT_NODE;
	this.TEXT_NODE = 3; //dom.TEXT_NODE;
	this.ATTR_COMPLEX = "complex";
	// ---
}


    /**
    * Method parses incoming XML data, creates controls structure.
    * Returns a list of top level controls
    *
    * @public
    * @method parse
    * @return {List}  collection of parsed controls
    */
    XmlDataParser.prototype.parse = function() {

        // find root node
        var nodes = this.getElementNodes(this.dom);

        // build controls structure from xml data, iterate nodes from the root level, build
        // control element from every node on this level
        var controls = new List();
        for (var it = nodes.iterator(); it.hasNext();) {
            var control = this.buildControl(it.next());
            controls.add(control);
        }

        // return parsed controls structure
        return controls;
    };


    /**
    * Filter dom child nodes - skipp all but ELEMENT_NODE nodes
    *
    * @private
    * @method  getElementNodes
    * @return  list of concrete child nodes
    */
    XmlDataParser.prototype.getElementNodes = function(element) {

        var nodes = new List();

        for (var i = 0; i < element.childNodes.length; i++) {

            var node = element.childNodes[i];
            if (node.nodeType == this.ELEMENT_NODE) {
                nodes.add(node);
            }
        }
        //
        return nodes;
    };

    /**
    * Build control and child control from xml dom structure
    *
    * @private
    * @method  buildControl
    * @param   {Node} element
    * @return  {MessUIElement} control object
    */
    XmlDataParser.prototype.buildControl = function(element) {

        // create control object
        var oControl = this.getNewControl(element);

        // iterate child nodes, create dependend control objects (recursive)
        var nodes = this.getElementNodes(element);
        for (var it = nodes.iterator(); it.hasNext();) {
            var nextNode = it.next();
            var nextControl = this.buildControl(nextNode)
            oControl.addControl(nextControl);
        }

        return oControl;
    }


    /**
    * Create new instance of control associated with node's tag. Initializes control
    * with node attribute values
    *
    * @private
    * @method  getNewControl
    * @param   {Node}  xml node
    * @return  {MessUIElement}  initialized control object
    */
    XmlDataParser.prototype.getNewControl = function(node) {

        // get control class
        var controlClass = MessUIElement.prototype.tagMappings.get(node.nodeName);
        // create control instance
        var control = eval("new "+controlClass+"();");
        // set control attributes
        for (var i = 0; i < node.attributes.length; i++) {

            var setterName = this.getSetterName(node.attributes[i].nodeName);
            eval("control."+setterName+"("+node.attributes[i].nodeValue+");");
        }
        // init control
        control.initControl();

        return control;
    };


    /**
    * Prepares attribute setter method name using attribute name
    *
    * @private
    * @method  getSetterName
    * @param   {String} attribute name
    * @return  {String} setter method name
    */
    XmlDataParser.prototype.getSetterName = function(name) {

        var setter = "set";
        var firstLetter = new String(name.charAt(0));
            firstLetter = firstLetter.toUpperCase();

        setter += firstLetter + name.substring(1, name.length);

        return setter;
    };

    /**
    * Returns attribute value. Tries to determine attribute value type.
    *
    * @private
    * @method  getAttributeValue
    * @param   {String} attribute node value
    * @return  {Object} object of specific attr. value type
    */
    XmlDataParser.prototype.getAttributeValue = function(value) {

        // okay, try to convert value into one of build in JavaScript types
        var converted = new Number(value);
        if (isNaN(converted)) {
            converted = new String(value);
        }

        return converted;
    };